SwiftUI Fix: Cannot Convert Binding<String?> to Binding in TextField

While working with TextField in SwiftUI, you might come across the following error:

Cannot convert value of type 'Binding<String?>' to expected argument type 'Binding'

This is a common issue when you're trying to bind a TextField to an optional String?, like in this example:

TextField("Address 2", text: $viewModel.business.address2)

Here, address2 is most likely declared as an optional string (String?), but TextField expects a non-optional Binding. Let’s walk through why this error happens and how to fix it.

Why This Happens

SwiftUI's TextField requires a binding to a concrete String, because it needs to show and update text consistently. Optional values introduce uncertainty: should the field show nil, an empty string, or something else?

That’s why you see this error — SwiftUI doesn’t know what to do with a Binding<String?>.

Solution 1: Manual Binding with Default Value

You can manually create a Binding from a Binding<String?> using Swift’s computed bindings:

TextField("Address 2", text: Binding(
    get: { viewModel.business.address2 ?? "" },
    set: { viewModel.business.address2 = $0 }
))

What This Does:

get: Returns the optional value if it exists, or an empty string if it's nil.

set: Updates the original optional with the new value from the text field.

This safely bridges the gap between the optional address2 and what TextField expects.

Bonus: Make It Reusable with an Extension

If you find yourself writing this conversion often, you can add a helpful extension:

extension Binding where Value == String? {
    func orEmpty() -> Binding<String> {
        Binding<String>(
            get: { self.wrappedValue ?? "" },
            set: { self.wrappedValue = $0 }
        )
    }
}

Now you can write:

TextField("Address 2", text: $viewModel.business.address2.orEmpty())